home *** CD-ROM | disk | FTP | other *** search
/ TOS Silver 2000 / TOS Silver 2000.iso / Anwendun / Pov / POVTOOLS / ATSIS / ATSIRDS.C < prev    next >
Encoding:
C/C++ Source or Header  |  1995-02-09  |  4.6 KB  |  191 lines

  1. /*************************************************************************
  2.                  ATsis -- create SIRDS out of depth information
  3.                  (C) 2/1995 by Christian Perle
  4.                  based on sirds program by W.A. Steer
  5.  *************************************************************************/
  6.  
  7. #include <stdio.h>
  8.  
  9. #ifndef SEEK_SET
  10. #define    SEEK_SET    0        /* from beginning of file */
  11. #define    SEEK_CUR    1        /* from current location */
  12. #define    SEEK_END    2        /* from end of file */
  13. #endif
  14.  
  15. #define RNDMASK 0x7FFF
  16. #define RNDDIVISOR (float) RNDMASK
  17.  
  18. #define SI_NAME "sirds.pbm"
  19.  
  20. /* depth of background in pixels */
  21. #define BKDEPTH -800
  22. /* eye separation in pixels */
  23. #define E 180
  24. /* observer-screen distance in pixels */
  25. #define O 700
  26. /* slow hidden point removal on/off */
  27. #define DOHIDDENREM 0
  28. /* width of picture in pixels */
  29. #define XRES 640
  30. /* height of picture in pixels */
  31. #define YRES 470
  32.  
  33. float rnd(void);
  34.  
  35. unsigned char  thedepth[XRES*YRES];
  36. unsigned char  pixels[XRES];
  37. unsigned char  thesird[XRES/8*(YRES+10)];  /* add 10 "help lines" */
  38. int  z[XRES];
  39. int  link[XRES];
  40.  
  41. static int  pw2[] = { 128, 64, 32, 16, 8, 4, 2, 1 };
  42.  
  43. FILE  *fd;
  44.  
  45. /* read depth file */
  46. read_depth(name)
  47. char  *name;
  48. {
  49.   int  x;
  50.  
  51.   fd = fopen(name, "rb");
  52.   if (fd == NULL) {
  53.     fprintf(stderr, "can't open %s\n", name);
  54.     exit(0);
  55.   }
  56.   for (x = 0; x < XRES*YRES; x++) thedepth[x] = fgetc(fd);
  57.   fclose(fd);
  58. }
  59.  
  60. /* add help marks */
  61. init_sirds()
  62. {
  63.   int  x, y, th;
  64.   float  helpdist;
  65.  
  66.   /* clear thesird[] array */
  67.   for (x = 0; x < XRES/8*(YRES+10); x++)
  68.     thesird[x] = 0;
  69.  
  70.   helpdist = abs(BKDEPTH)*E/(2.0*(abs(BKDEPTH)+O));
  71.   th = 0;
  72.   for (y = 9; y >= 0; y--) {
  73.     /* left mark */
  74.     for (x = XRES/2-helpdist-th; x <= XRES/2-helpdist+th; x++) {
  75.       thesird[y*XRES/8+x/8] |= pw2[x % 8];
  76.     }
  77.     /* right mark */
  78.     for (x = XRES/2+helpdist-th; x <= XRES/2+helpdist+th; x++) {
  79.       thesird[y*XRES/8+x/8] |= pw2[x % 8];
  80.     }
  81.     th++;
  82.   }
  83. }
  84.  
  85. /* render the SIRDS */
  86. do_sirds()
  87. {
  88.   int  x, y, h, u, dx, highest, separation, left, right;
  89.   int  c, visible;
  90.   float  v;
  91.  
  92.   for (y = 0; y < YRES; y++) {
  93.     fprintf(stderr, "Rendering line %4d of %4d\r", y+1, YRES);
  94.     for (x = 0; x < XRES*1; x++) link[x] = x;
  95.     highest = BKDEPTH;
  96.     for (x = 0; x < XRES; x++) {
  97.       h = BKDEPTH + thedepth[y*XRES+x];
  98.       z[x] = h;
  99.       if (h > highest) highest = h;
  100.     }
  101.     for (x = 0; x < XRES*1; x++) {
  102.       separation = (E*1*z[x/1])/(z[x/1]-O);
  103.       left = x-separation/2;
  104.       right = left+separation;
  105.       if ((left >= 0) && (right < XRES*1)) {
  106.         visible = 1;
  107.         if (DOHIDDENREM == 1) {
  108.           v = 2.0*(O-z[x/1])/E;
  109.           dx = 1;
  110.           do {
  111.             u = z[x/1]+dx*v;
  112.             if ((z[(x+dx)/1] >= u) || (z[(x-dx)/1] >= u))
  113.               visible = 0;
  114.             dx++;
  115.           } while ((u <= highest) && (visible == 1));
  116.         }
  117.         if (visible == 1) link[right] = left;
  118.       }
  119.     }
  120.     for (x = 0; x < XRES*1; x++) {
  121.       if (link[x] == x) {
  122.         pixels[x] = (int)2*rnd();
  123.       }
  124.       else {
  125.         pixels[x] = pixels[link[x]];
  126.       }
  127.     }
  128.     for (x = 0; x < XRES; x++)
  129.       if (pixels[x] == 1) thesird[(y+10)*XRES/8+x/8] |= pw2[x % 8];
  130.   }
  131. }
  132.  
  133. /* write SIRDS as PBM file */
  134. write_sirds_pbm()
  135. {
  136.   int  x;
  137.  
  138.   fd = fopen(SI_NAME, "wb");
  139.   fprintf(fd, "P4\n");
  140.   fprintf(fd, "%d %d\n", XRES, YRES+10);
  141.   for (x = 0; x < XRES/8*(YRES+10); x++) fputc(thesird[x],fd);
  142.   fclose(fd);
  143. }
  144.  
  145. /* return random value between 0 and 1 */
  146. float rnd(void)
  147. {
  148.   float  z;
  149.  
  150.   z = (float) (rand() & RNDMASK) / (RNDDIVISOR+1);
  151.   return(z);
  152. }
  153.  
  154. /* --------------------------------------------------------------------- */
  155.  
  156. main(argc, argv)
  157. int  argc;
  158. char  *argv[];
  159. {
  160.   int  argn;
  161.   char  *de_name;
  162.  
  163.   fprintf(stderr, "ATsirds v1.0  (C) 2/1995 Christian Perle\n");
  164.   fprintf(stderr, "based on sirds program by W.A. Steer\n\n");
  165.   argn = 1;  /* number of arguments */
  166.   if (argn < argc) {
  167.     de_name = argv[argn];
  168.     argn++;
  169.   }
  170.   else {  /* too few arguments */
  171.     fprintf(stderr, "usage: atsirds depthfile\n");
  172.     exit(0);
  173.   }
  174.   if (argn != argc) {  /* too much arguments */
  175.     fprintf(stderr, "usage: atsirds depthfile\n");
  176.     exit(0);
  177.   }
  178.   fprintf(stderr, "Rendering %s to ", de_name);
  179.   fprintf(stderr, SI_NAME);
  180.   fprintf(stderr, "\n");
  181.   fprintf(stderr, "Size %dx%d", XRES, YRES+10);
  182.   if (DOHIDDENREM == 1) fprintf(stderr, ", hidden point removal.\n\n");
  183.   else fprintf(stderr, ".\n\n");
  184.   read_depth(de_name);
  185.   init_sirds();
  186.   do_sirds();
  187.   fprintf(stderr, "\n");
  188.   write_sirds_pbm();
  189.   fprintf(stderr, "Done.\n");
  190. }
  191.